package com.warmguard.core.exception;

import cn.hutool.core.util.StrUtil;

import com.warmguard.core.enums.ResultCodeEnum;
import com.warmguard.core.exception.error.ErrorCodeInterface;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

/**
 * 统一异常类
 *
 * @author valarchie
 */
@EqualsAndHashCode(callSuper = true)
@Slf4j
@Data
public class ServiceException extends RuntimeException {

    // code message  i18key
    protected ErrorCodeInterface errorCode;

    // 错误信息
    protected String message;

    // i18key 对应的value
    protected String i18nMessage;

    /**
     * 如果有一些特殊的数据  可以放在这个payload里面
     * 有时候错误的返回信息太少  不便前端处理的话  可以放在这个payload字段当中
     * 比如你做了一个大批量操作，操作ID为1~10的实体， 其中1~5成功   6~10失败
     * 你可以将这些相关信息放在这个payload中
     */
    protected HashMap<String, Object> payload;

    public ServiceException(ErrorCodeInterface errorCode) {
        fillErrorCode(errorCode);
    }

    public ServiceException(ErrorCodeInterface errorCode, Object... args) {
        fillErrorCode(errorCode, args);
    }

    /**
     * 注意  如果是try catch的情况下捕获异常 并转为ApiException的话  一定要填入Throwable e
     *
     * @param e         捕获到的原始异常
     * @param errorCode 错误码
     * @param args      错误详细信息参数
     */
    public ServiceException(Throwable e, ErrorCodeInterface errorCode, Object... args) {
        super(e);
        fillErrorCode(errorCode, args);
    }

    public ServiceException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.errorCode = resultCodeEnum;
    }

    private void fillErrorCode(ErrorCodeInterface errorCode, Object... args) {
        this.errorCode = errorCode;
        this.message = StrUtil.format(errorCode.message(), args);
    }

    // 优先返回 i18 的错误消息
    @Override
    public String getMessage() {
        return message;
    }


}
